//
//  EditAddressView.swift
//  GreenDeal
//
//  Created by Moennig Q on 22/2/2023.
//  注册页面和创建Job页面共用的根据输入的Address，分解获取address信息的View

import UIKit
import SnapKit
import RxGesture
import RxCocoa
import RxSwift
import HandyJSON
class PhysicalAddressViewModel: NSObject, HandyJSON {
    var address_id: String = ""
    @objc dynamic var unit_type: String = ""
    var unit_type_name: String = ""
    @objc dynamic var unit_number: String = ""
    
    @objc dynamic var street_type: String = ""
    var street_type_name: String = ""
    @objc dynamic var street_number: String = ""
    @objc dynamic var street_name: String = ""
    @objc dynamic var state: String = ""
    @objc dynamic var suburb: String = ""
    @objc dynamic var post_code: String = ""
    var full_address: String = ""
    var latitude: String = ""
    var longitude: String = ""
    var post_code_display_name: String {
        var returnStr = ""
        if self.suburb != ""{
            returnStr = self.suburb
        }
        if self.state != ""{
            returnStr += " " + self.state
        }
        if self.post_code != ""{
            returnStr += " " + self.post_code
        }
        return returnStr
    }
    //（A:user选择地址后，又做了编辑; B:没有选地址直接自己编辑的地址）最终的address, 如果和full address就讲address id清空，且讲final_full_address赋值给full address
    var final_full_address: String {
        var returnStr = ""
        //unit_type
        if self.unit_type != "" {
            returnStr = unit_type + " "
        }
        //unit_number
        if self.unit_number != "" {
            returnStr += unit_number + " "
        }
        //street_number
        if self.street_number != "" {
            returnStr += street_number + " "
        }
        //street_name
        if self.street_name != "" {
            returnStr += street_name + " "
        }
        //street_type
        if self.street_type != "" {
            returnStr += street_type
        }
        //用逗号分割
        if returnStr.count > 0 {
            returnStr += ", "
        }
        //suburb
        if self.suburb != ""{
            returnStr += self.suburb + " "
        }
        //state
        if self.state != ""{
            returnStr += self.state + " "
        }
        //post code
        if self.post_code != ""{
            returnStr += self.post_code
        }
        return returnStr
    }
    required override init() {
        
    }
}
class PhysicalAddressView: View {
    lazy var disposeBag = DisposeBag()
    var addressModel = PhysicalAddressViewModel()
    let searchTextfield = DIYTextField()
    //
    let addressView = UIView()
    let unitTypeTextfield = TextFieldWithRequiredView()
    let unitNoTextfield = TextFieldWithRequiredView()
    let streetTypeTextfield = TextFieldWithRequiredView()
    
    let streetNoLabel = LabelWithRedStarView(R.string.localizable.streetNo())
    let streetNameLabel = LabelWithRedStarView(R.string.localizable.streetName())
    let streetTypeLabel = LabelWithRedStarView(R.string.localizable.streetType())
    let streetNoTextfield = TextFieldWithRequiredView()
    let streetNameTextfield = TextFieldWithRequiredView()
    let postcodeTextfield = TextFieldWithRequiredView(.postCode)
    var postalAddressFlag: Bool = false
    //
    var everythingValidFlag: Bool = true
    override func setUpView() {
        //search textfield
        searchTextfield.placeholder = R.string.localizable.searchForAnAddress()
        searchTextfield.showRightImageView("edit_address_search_icon") {[weak self] in
            self?.searchAddress()
        }
        searchTextfield.returnKeyType = .search
        self.addSubview(searchTextfield)
        searchTextfield.snp.makeConstraints { make in
            make.left.top.right.equalToSuperview()
            make.height.equalTo(DIYTextField.height)
        }
        //searchTipLabel
        let searchTipLabel = ContentLabel(R.font.interRegular(size: 11),hexStr: "#292D3299")
        searchTipLabel.text = R.string.localizable.eGUnitOptional123SampleStreetSydneyNSW2000()
        searchTipLabel.numberOfLines = 0
        self.addSubview(searchTipLabel)
        searchTipLabel.snp.makeConstraints { make in
            make.top.equalTo(searchTextfield.snp.bottom).offset(4)
            make.left.right.equalTo(searchTextfield)
            make.height.greaterThanOrEqualTo(0)
        }
        //addressView
        addressView.drawCorner(byRoundingCorners: .allCorners,radii: Constant.StandardCornerRadius, backColorHexStr: "#9FACBE33")
        self.addSubview(addressView)
        addressView.snp.makeConstraints { make in
            make.top.equalTo(searchTipLabel.snp.bottom).offset(Constant.TopBottomMargin)
            make.left.right.equalToSuperview()
            make.height.greaterThanOrEqualTo(0)
            make.bottom.equalToSuperview()
        }
        //unitType
        let unitTypeLabel = ContentLabel(hexStr: Constant.NotRequiredTitleColorHexStr)
        unitTypeLabel.text = R.string.localizable.unitType()
        addressView.addSubview(unitTypeLabel)
        unitTypeLabel.snp.makeConstraints { make in
            make.top.equalTo(Constant.TopBottomMargin)
            make.left.equalTo(Constant.LeftRightMargin)
            make.height.width.greaterThanOrEqualTo(0)
        }
        unitTypeTextfield.textField.placeholder = R.string.localizable.pleaseSelect()
        unitTypeTextfield.textField.showRightImageView("installation_list_search_down_arrow")
        addressView.addSubview(unitTypeTextfield)
        unitTypeTextfield.snp.makeConstraints { make in
            make.top.equalTo(unitTypeLabel.snp.bottom).offset(Constant.TitleTextMargin)
            make.left.equalTo(unitTypeLabel)
            make.width.height.greaterThanOrEqualTo(0)
        }
        //unitType
        unitNoTextfield.textField.clearButtonMode = .always
        addressView.addSubview(unitNoTextfield)
        unitNoTextfield.snp.makeConstraints { make in
            make.top.equalTo(unitTypeTextfield)
            make.left.equalTo(unitTypeTextfield.snp.right).offset(Constant.InternalMargin)
            make.width.equalTo(unitTypeTextfield)
            make.right.equalTo(-Constant.LeftRightMargin)
            make.height.greaterThanOrEqualTo(0)
        }
        
        let unitNoLabel = ContentLabel(hexStr: Constant.NotRequiredTitleColorHexStr)
        unitNoLabel.text = R.string.localizable.unitNo()
        addressView.addSubview(unitNoLabel)
        unitNoLabel.snp.makeConstraints { make in
            make.top.equalTo(unitTypeLabel)
            make.left.equalTo(unitNoTextfield)
            make.height.width.greaterThanOrEqualTo(0)
        }
        //streetNo
        addressView.addSubview(streetNoLabel)
        streetNoLabel.snp.makeConstraints { make in
            make.top.equalTo(unitNoTextfield.snp.bottom).offset(Constant.TopBottomMargin)
            make.left.equalTo(unitTypeLabel)
            make.height.width.greaterThanOrEqualTo(0)
        }
        streetNoTextfield.textField.clearButtonMode = .always
        addressView.addSubview(streetNoTextfield)
        streetNoTextfield.snp.makeConstraints { make in
            make.top.equalTo(streetNoLabel.snp.bottom).offset(Constant.TitleTextMargin)
            make.left.equalTo(unitTypeLabel)
            make.height.greaterThanOrEqualTo(0)
            make.width.equalTo(unitTypeTextfield)
        }
        //street type
        addressView.addSubview(streetTypeLabel)
        streetTypeLabel.snp.makeConstraints { make in
            make.left.equalTo(unitNoLabel)
            make.top.equalTo(streetNoLabel)
            make.height.width.greaterThanOrEqualTo(0)
        }
        streetTypeTextfield.textField.isEnabled = false
        streetTypeTextfield.textField.placeholder = R.string.localizable.pleaseSelect()
        streetTypeTextfield.textField.showRightImageView("installation_list_search_down_arrow")
        addressView.addSubview(streetTypeTextfield)
        streetTypeTextfield.snp.makeConstraints { make in
            make.left.equalTo(unitNoLabel)
            make.top.equalTo(streetNoTextfield)
            make.height.greaterThanOrEqualTo(0)
            make.width.equalTo(unitTypeTextfield)
        }
        //street name
        addressView.addSubview(streetNameLabel)
        streetNameLabel.snp.makeConstraints { make in
            make.top.equalTo(streetNoTextfield.snp.bottom).offset(Constant.TopBottomMargin)
            make.left.equalTo(streetNoLabel)
            make.height.width.greaterThanOrEqualTo(0)
        }
        streetNameTextfield.textField.clearButtonMode = .always
        addressView.addSubview(streetNameTextfield)
        streetNameTextfield.snp.makeConstraints { make in
            make.top.equalTo(streetNameLabel.snp.bottom).offset(Constant.TitleTextMargin)
            make.left.equalTo(unitTypeLabel)
            make.right.equalTo(unitNoTextfield)
            make.height.greaterThanOrEqualTo(0)
        }
        //suburb
        let suburbLabel = LabelWithRedStarView(R.string.localizable.suburb())
        addressView.addSubview(suburbLabel)
        suburbLabel.snp.makeConstraints { make in
            make.top.equalTo(streetNameTextfield.snp.bottom).offset(Constant.TopBottomMargin)
            make.left.equalTo(streetNoLabel)
            make.height.width.greaterThanOrEqualTo(0)
        }
        
        postcodeTextfield.textField.placeholder = R.string.localizable.typePostcodeToSearch()
        postcodeTextfield.textField.clearButtonMode = .always
        postcodeTextfield.textField.keyboardType = .numberPad
        addressView.addSubview(postcodeTextfield)
        postcodeTextfield.snp.makeConstraints { make in
            make.top.equalTo(suburbLabel.snp.bottom).offset(Constant.TitleTextMargin)
            make.left.equalTo(unitTypeLabel)
            make.right.equalTo(unitNoTextfield)
            make.height.greaterThanOrEqualTo(0)
            make.bottom.equalTo(-Constant.TopBottomMargin)
        }
        //搜索地址
        searchTextfield.rx.controlEvent(UIControl.Event.editingDidBegin).asObservable().subscribe(onNext: {[weak self] _ in
            self?.searchAddress()
        }).disposed(by: self.disposeBag)
        //search 图标的点击事件，根据post code 选择state ,suburb
        postcodeTextfield.textField.showRightImageView("edit_address_search_icon") {
            self.endEditing(true)
            let postCode = self.addressModel.post_code
            Tool().showSearchAddressDictionaryView(type: .postcode,showPleaseSleectFlag: false, title: R.string.localizable.suburb(),defaultSearchValue: postCode) { [weak self] (result) in
                guard let strongSelf = self else { return}
                strongSelf.setSuburbInfo(result)
                strongSelf.postcodeTextfield.hideInvalidMsg()
            }
        }
        //选择unit type
        unitTypeTextfield.textField.clearButtonMode = .never//不显示clear按钮
        unitTypeTextfield.textField.isEnabled = false
        unitTypeTextfield.rx.tapGesture().when(.recognized).subscribe(onNext: {[weak self] _ in
            guard let strongSelf = self else {return}
            strongSelf.selectUnitType()
        }).disposed(by: self.disposeBag)
        //监听unit type的值，没有值时，unit no置灰，有值才能编辑
        unitTypeTextfield.textField.rx.observe(String.self, "text").subscribe {[weak self] (text) in
            guard let strongSelf = self, let unitType = text else {return }
            if unitType == "" {
                strongSelf.unitNoTextfield.textField.isEnabled = false
                strongSelf.unitNoTextfield.textField.backgroundColor = UIColor(hexStr: "#292D3233")
                strongSelf.addressModel.unit_number = ""
                strongSelf.unitNoTextfield.textField.text = ""
                strongSelf.unitNoTextfield.changeCheckFlag(false)
            }else{
                strongSelf.unitNoTextfield.textField.isEnabled = true
                strongSelf.unitNoTextfield.textField.backgroundColor = UIColor.white
                strongSelf.unitNoTextfield.changeCheckFlag(true)
            }
            
        }.disposed(by: self.disposeBag)
        //选择street type
        streetTypeTextfield.textField.clearButtonMode = .never//不显示clear按钮
        streetTypeTextfield.rx.tapGesture().when(.recognized).subscribe(onNext: {[weak self] _ in
            guard let strongSelf = self else {return}
            strongSelf.selectStreetType(showPleaseSleectFlag: strongSelf.postalAddressFlag)//post address时，street type是非必填的，所有要显示please select
        }).disposed(by: self.disposeBag)
        //编辑完自动获取事件(针对postcode查出一个地址)
        postcodeTextfield.editingDidEndClosure = { [weak self]  (data) in
            guard let strongSelf = self else {return}
            //0.现将当前值赋值上，只保留post code，将state，suburb情况
            strongSelf.checkPostCode(data)
        }
        //监听unitNo编辑内容
        unitNoTextfield.editingDidEndClosure = {[weak self] (data)in
            guard let strongSelf = self else {return }
            let oldValue = strongSelf.addressModel.unit_number
            strongSelf.addressModel.unit_number = data
            strongSelf.resetFullAddressInfo(oldValue: oldValue, newValue: data,resetFlag: false)
        }
        //监听streetNo编辑内容
        streetNoTextfield.editingDidEndClosure = {[weak self] (data)in
            guard let strongSelf = self else {return }
            let oldValue = strongSelf.addressModel.street_number
            strongSelf.addressModel.street_number = data
            strongSelf.resetFullAddressInfo(oldValue: oldValue, newValue: data,resetFlag: true)
        }
        
        //监听streetNo编辑内容
        streetNameTextfield.editingDidEndClosure = {[weak self] (data)in
            guard let strongSelf = self else {return }
            let oldValue = strongSelf.addressModel.street_name
            strongSelf.addressModel.street_name = data
            strongSelf.resetFullAddressInfo(oldValue: oldValue, newValue: data,resetFlag: true)
        }
        //每次使用物理地址编辑，都调用地址基础数据的拉取
        DBManager.shared.upgradeSettingData()
        self.checkIfEverytingValid()//数据绑定所有的必填字段是否有效
    }
    //MARK: - //true的话street no,street name是非必填项，false的话street no,street name是必填项
    func dealIfCheckStreetNoAndStreetName(_ postalAddressFlag: Bool){
        self.postalAddressFlag = postalAddressFlag
        //post address是非必填
        streetNoLabel.showRedStar(!postalAddressFlag)//
        streetNameLabel.showRedStar(!postalAddressFlag)//
        streetTypeLabel.showRedStar(!postalAddressFlag)//
        streetNoTextfield.needCheckFlag = !postalAddressFlag
        streetNameTextfield.needCheckFlag = !postalAddressFlag
        streetTypeTextfield.needCheckFlag = !postalAddressFlag
    }
    //MARK: - 根据输入的post code查找相关的suburb state info,直接复制
    private func setSuburbInfo(_ addressModel: PhysicalAddressViewModel){
        //设置文本
        let oldValue = self.addressModel.post_code_display_name
        let newValue = addressModel.post_code_display_name
        //数据
        self.addressModel.post_code = addressModel.post_code
        self.addressModel.state = addressModel.state
        self.addressModel.suburb = addressModel.suburb
        //
        self.resetFullAddressInfo(oldValue: oldValue, newValue: newValue,resetFlag: true)
        //
        self.postcodeTextfield.textField.text = addressModel.post_code_display_name
        
    }
    //MARK: - 选择unit type
    private func selectUnitType(){
        self.endEditing(true)
        Tool().showSearchAddressDictionaryView(type: .unitType,showPleaseSleectFlag: true,title: R.string.localizable.unitType()) {[weak self] (result) in
            guard let strongSelf = self else { return}
            if result.unit_type == "" {
                strongSelf.unitTypeTextfield.textField.text = ""
                strongSelf.unitNoTextfield.textField.text = ""
                strongSelf.addressModel.unit_type_name = ""
                strongSelf.addressModel.unit_type = ""
                strongSelf.addressModel.unit_number = ""
            }else{
                strongSelf.unitTypeTextfield.textField.text = result.unit_type_name
                strongSelf.addressModel.unit_type_name = result.unit_type_name
                strongSelf.addressModel.unit_type = result.unit_type
            }
            //处理是否需要重置address id和full address
            strongSelf.resetFullAddressInfo(oldValue: strongSelf.addressModel.unit_type, newValue: result.unit_type,resetFlag: false)
        }
    }
    //MARK: - 选择Street type,showPleaseSleectFlag是否显示Please Sleect空选项
    private func selectStreetType(showPleaseSleectFlag: Bool){
        self.endEditing(true)
        Tool().showSearchAddressDictionaryView(type: .streetType,showPleaseSleectFlag: showPleaseSleectFlag,title: R.string.localizable.streetType()) {[weak self] (result) in
            guard let strongSelf = self else { return}
            if result.street_type == "" {
                strongSelf.streetTypeTextfield.textField.text = ""
                strongSelf.addressModel.street_type_name = ""
                strongSelf.addressModel.street_type = ""
            }else{
                strongSelf.streetTypeTextfield.textField.text = result.street_type_name
                strongSelf.addressModel.street_type_name = result.street_type_name
                strongSelf.addressModel.street_type = result.street_type
            }
            strongSelf.streetTypeTextfield.checkTextIfValid()
            //处理是否需要重置address id和full address
            strongSelf.resetFullAddressInfo(oldValue: strongSelf.addressModel.street_type, newValue: result.street_type,resetFlag: true)
            
            
        }
    }
    //MARK: - 根据输入的post code查找相关的suburb state info,直接复制
    private func checkPostCode(_ content: String){
        if content == self.addressModel.post_code_display_name{
            return
        }
        guard content.count >= 4 else {
            //
            self.addressModel.post_code = content
            self.addressModel.state = ""
            self.addressModel.suburb = ""
            return
        }
        let postCode = String(content.suffix(4))//取最后四位，因为postcodeTextfield显示的是suburb + state + postcode的组合
        let list = DBManager.shared.getSuburbListByPostcode(postCode)
        if list.count == 0{//没有地址返回
            self.postcodeTextfield.showInvalidMsg(R.string.localizable.noSuburbMatchingThatPostcodeFound())
            let addressModel = PhysicalAddressViewModel()
            addressModel.post_code = postCode
            self.setSuburbInfo(addressModel)
        }else{
            if list.count == 1 {//只返回一个，就自动复制
                self.setSuburbInfo(list[0])
            }else{//返回多个地址，自动弹出搜索框
                let addressModel = PhysicalAddressViewModel()
                addressModel.post_code = postCode
                self.setSuburbInfo(addressModel)
                Tool().showSearchAddressDictionaryView(type: .postcode,showPleaseSleectFlag: false,title: R.string.localizable.suburb(),defaultSearchValue: addressModel.post_code) {[weak self] (result) in
                    guard let strongSelf = self else { return}
                    if result.post_code == ""{//为空表示没有选择suburb，直接关闭了搜索框
                        strongSelf.postcodeTextfield.showInvalidMsg(R.string.localizable.pleaseSelectOneSuburb())
                    }else{
                        strongSelf.setSuburbInfo(result)
                    }
                }
            }
        }
    }
    //MARK: - 根据输入的address搜索解析地址
    func searchAddress(){
        self.endEditing(true)
        Tool().showSearchAddressView() {[weak self] (result) in
            guard let strongSelf = self else { return}
            strongSelf.addressModel.unit_type = result.unit_type
            strongSelf.addressModel.unit_number = result.unit_number
            strongSelf.addressModel.street_number = result.street_number
            strongSelf.addressModel.street_type = result.street_type
            strongSelf.addressModel.street_name = result.street_name
            strongSelf.addressModel.post_code = result.post_code
            strongSelf.addressModel.state = result.state
            strongSelf.addressModel.suburb = result.suburb
            strongSelf.addressModel.full_address = result.full_address
            strongSelf.addressModel.latitude = result.latitude
            strongSelf.addressModel.longitude = result.longitude
            
            //
            if strongSelf.addressModel.street_type != ""{
                strongSelf.addressModel.street_type_name = DBManager.shared.getStreetTypeNameByValue(strongSelf.addressModel.street_type)
            }
            //
            strongSelf.unitNoTextfield.textField.text = strongSelf.addressModel.unit_number
            strongSelf.unitTypeTextfield.textField.text = strongSelf.addressModel.unit_type
            strongSelf.streetNoTextfield.textField.text = strongSelf.addressModel.street_number
            strongSelf.streetTypeTextfield.textField.text = strongSelf.addressModel.street_type_name
            strongSelf.streetNameTextfield.textField.text = strongSelf.addressModel.street_name
            strongSelf.postcodeTextfield.textField.text = strongSelf.addressModel.post_code_display_name
            //校验必填项，隐藏必填项的tip msg
            strongSelf.streetNoTextfield.checkTextIfValid()
            strongSelf.streetTypeTextfield.checkTextIfValid()
            strongSelf.streetNameTextfield.checkTextIfValid()
            if strongSelf.addressModel.state == "" || strongSelf.addressModel.suburb == "" || strongSelf.addressModel.post_code == ""{//为空才校验，直接校验如果有多个数据，会自动弹出萱蕚subub的弹出框
                strongSelf.postcodeTextfield.checkTextIfValid()
            }else{
                strongSelf.postcodeTextfield.hideInvalidMsg()
            }
            
        }
    }
    
    //设置地址信息时，重置address id 和full address
    //resetFlag,修改了unit type，unit no，不置空经纬度；修改了street no， street type，street name，suburb才认为置空经纬度
    private func resetFullAddressInfo(oldValue: String, newValue: String, resetFlag: Bool){
        if oldValue != newValue {
            if resetFlag {//
                self.addressModel.latitude = ""
                self.addressModel.longitude = ""
                self.addressModel.address_id = ""
            }
            self.addressModel.full_address = self.addressModel.final_full_address
        }
        
    }
    func setData(_ model: PhysicalAddressViewModel){
        self.addressModel = model
        self.unitNoTextfield.textField.text = addressModel.unit_number
        self.unitTypeTextfield.textField.text = addressModel.unit_type_name
        self.streetNoTextfield.textField.text = addressModel.street_number
        self.streetTypeTextfield.textField.text = addressModel.street_type_name
        self.streetNameTextfield.textField.text = addressModel.street_name
        self.postcodeTextfield.textField.text = addressModel.post_code_display_name
    }
    //MARK: - 只用于已创建Job的信息编辑， 进入编辑界面如果save 按钮不可用，要给与相应提示
    func validateAllRequiredFieldWhenEdit(){
        if self.unitNoTextfield.textField.isEnabled {//如果选择了unit type，则unit no是必填的
            self.unitNoTextfield.checkIfStandardValid()
        }
        //street type
        self.streetTypeTextfield.checkIfStandardValid()
        self.streetNoTextfield.checkIfStandardValid()
        self.streetNameTextfield.checkIfStandardValid()
        self.postcodeTextfield.checkIfStandardValid()//是否为空
        if self.postcodeTextfield.validStatus.value == .valid {//不为空
            if addressModel.state == "" && addressModel.suburb == "" {//为空才校验
                self.postcodeTextfield.showInvalidMsg(R.string.localizable.pleaseSelectOneSuburb())
            }
        }
    }
    //MARK: - 校验所有的必填项是否有效
    private func checkIfEverytingValid(){
        //1.install address
        let unitTypeValid = self.addressModel.rx.observe(String.self, "unit_type").map({($0 ?? "").count > 0}).share(replay: 1)
        let unitNoValid = self.addressModel.rx.observe(String.self, "unit_number").map({($0 ?? "").count > 0}).share(replay: 1)
        let streetTypeValid = self.addressModel.rx.observe(String.self, "street_type").map({($0 ?? "").count > 0}).share(replay: 1)
        let streetNameValid = self.addressModel.rx.observe(String.self, "street_name").map({($0 ?? "").count > 0}).share(replay: 1)
        let streetNumberValid = self.addressModel.rx.observe(String.self, "street_number").map({($0 ?? "").count > 0}).share(replay: 1)
        let stateValid = self.addressModel.rx.observe(String.self, "state").map({($0 ?? "").count > 0}).share(replay: 1)
        let suburbValid = self.addressModel.rx.observe(String.self, "suburb").map({($0 ?? "").count > 0}).share(replay: 1)
        let postcodeValid = self.addressModel.rx.observe(String.self, "post_code").map({($0 ?? "").count > 0}).share(replay: 1)
        //combine
        let everythingValid = Observable.combineLatest(
            unitTypeValid,
            unitNoValid,
            streetTypeValid,
            streetNameValid,
            streetNumberValid,
            stateValid,
            suburbValid,
            postcodeValid
        ) { ($0 && $1 || !$0 && !$1) && $2 && $3 && $4 && $5 && $6 && $7}
            .share(replay: 1)
        
        everythingValid.subscribe { [weak self] (valid) in
            guard let strongSelf = self else {return}
            strongSelf.everythingValidFlag = valid
        }.disposed(by: self.disposeBag)
    }
}

